<template>
  <div class="relative">
    <div class="flex justify-end py-2 absolute right-1 top-.5 z-10">
      <el-popover placement="bottom-start" trigger="hover" width="220">
        <template #reference>
          <ElButton :icon="Setting" circle size="small" />
        </template>
        <draggable v-model="tableColumns" :canDelete="false" :add="false">
          <template #item="{ element }">
            <el-checkbox :label="element.title" v-model="element.visible" />
          </template>
        </draggable>
      </el-popover>
    </div>
    <div :style="{ height: height }">
      <el-auto-resizer>
        <template #default="{ height: autoHeight, width: autoWidth }">
          <el-table-v2
            ref="tableRef"
            :data="data"
            :loading="loading"
            v-bind="tableSetProps"
            :columns="showColumns"
            :width="autoWidth"
            :height="autoHeight"
          >
            <template v-for="(_, name) in slots" #[name]="slotData">
              <slot :name="name" v-bind="slotData || {}"></slot>
            </template>
          </el-table-v2>
        </template>
      </el-auto-resizer>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, watch, useSlots } from 'vue'
import { Setting } from '@element-plus/icons-vue'
import { ElButton, ElTableV2 } from 'element-plus'

import { ScheduleRecordApi } from '@/api/distm/schedule/index'
import { objectEq } from '@/utils/eq'

defineOptions({ name: 'TableV2' })

let lastChangedColumn: any[] = []

const props = withDefaults(
  defineProps<{
    columns: any[]
    data: any[]
    loading?: boolean
    tableSetProps?: any
    height: string
    columnSaveKey?: string
  }>(),
  {
    loading: false,
    tableSetProps: () => ({}),
    columns: () => [],
    data: () => [],
    height: '52vh'
  }
)
const tableRef = ref()
const slots = useSlots()

const tableColumns = ref(
  props.columns
    .filter((col) => col.key != 'actions')
    .map((col) => ({
      ...col,
      visible: true
    }))
)

if (props.columnSaveKey) {
  ScheduleRecordApi.getTableitem(props.columnSaveKey).then((res) => {
    if (res && res.length > 0) {
      lastChangedColumn = res || []
      const columns = props.columns
        .filter((col) => col.key != 'actions')
        .map((col, index) => {
          const savedCol = lastChangedColumn.find((sc: any) => sc.prop === col.key)
          return {
            ...col,
            visible: savedCol ? savedCol.visible : true,
            sort: savedCol ? savedCol.sort : index + 1
          }
        })
      // 根据 sort 排序
      columns.sort((a, b) => a.sort - b.sort)
      tableColumns.value = columns
    }
  })
}

const showColumns = computed(() => {
  return tableColumns.value
    .filter((col) => col.visible)
    .concat(props.columns.filter((col) => col.key == 'actions'))
})

watch(
  () => props.columns,
  (newCols) => {
    const columns = newCols
      .filter((col) => col.key != 'actions')
      .map((col, index) => {
        const savedCol = lastChangedColumn.find((sc: any) => sc.prop === col.key)
        return {
          ...col,
          visible: savedCol ? savedCol.visible : true,
          sort: savedCol ? savedCol.sort : index + 1
        }
      })
    columns.sort((a, b) => a.sort - b.sort)
    tableColumns.value = columns
  }
)

watch(
  () => tableColumns.value,
  (newCols) => {
    if (!props.columnSaveKey) {
      return
    }
    const saveColumns = newCols.map((col, index) => ({
      prop: col.key,
      sort: index + 1,
      visible: col.visible
    }))
    if (objectEq(lastChangedColumn, saveColumns)) {
      return
    }
    lastChangedColumn = saveColumns
    ScheduleRecordApi.updateTableitem({
      tableType: props.columnSaveKey,
      props: saveColumns
    })
  },
  { deep: true }
)
</script>
